{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: tqdm in d:\\program\\anaconda\\envs\\ai\\lib\\site-packages (4.46.0)\n",
      "Requirement already satisfied: lightgbm in d:\\program\\anaconda\\envs\\ai\\lib\\site-packages (2.3.0)\n",
      "Requirement already satisfied: scikit-learn in d:\\program\\anaconda\\envs\\ai\\lib\\site-packages (from lightgbm) (0.22.1)\n",
      "Requirement already satisfied: numpy in d:\\program\\anaconda\\envs\\ai\\lib\\site-packages (from lightgbm) (1.17.4)\n",
      "Requirement already satisfied: scipy in d:\\program\\anaconda\\envs\\ai\\lib\\site-packages (from lightgbm) (1.3.2)\n",
      "Requirement already satisfied: joblib>=0.11 in d:\\program\\anaconda\\envs\\ai\\lib\\site-packages (from scikit-learn->lightgbm) (0.14.1)\n"
     ]
    }
   ],
   "source": [
    "! pip install tqdm\n",
    "! pip install lightgbm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from tqdm import tqdm\n",
    "from sklearn.metrics import mean_squared_error,explained_variance_score\n",
    "from sklearn.model_selection import KFold\n",
    "import lightgbm as lgb\n",
    "import math\n",
    "import os\n",
    "from joblib import Parallel, delayed\n",
    "\n",
    "test_data_path = '../data/testData0626.csv'\n",
    "route_order_folder_path = '../data/route_order_data'\n",
    "port_path = '../data/port.csv'\n",
    "result_path = '../result_20200627_B_origin_edit.csv'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def format_data_type(data, mode='train'):\n",
    "    if mode=='test':\n",
    "        data['onboardDate'] = pd.to_datetime(data['onboardDate'], infer_datetime_format=True)\n",
    "        data['temp_timestamp'] = data['timestamp']\n",
    "        data['ETA'] = None\n",
    "        data['creatDate'] = None\n",
    "    data['loadingOrder'] = data['loadingOrder'].astype(str)\n",
    "    data['timestamp'] = pd.to_datetime(data['timestamp'], infer_datetime_format=True)\n",
    "    data['longitude'] = data['longitude'].astype(float)\n",
    "    data['latitude'] = data['latitude'].astype(float)\n",
    "    data['speed'] = data['speed'].astype(float)\n",
    "    data['TRANSPORT_TRACE'] = data['TRANSPORT_TRACE'].astype(str)\n",
    "    return data\n",
    "\n",
    "def get_test_data_info(path):\n",
    "    data = pd.read_csv(path) \n",
    "    test_trace_set = data['TRANSPORT_TRACE'].unique()\n",
    "    test_order_belong_to_trace = {}\n",
    "    for item in test_trace_set:\n",
    "        orders = data[data['TRANSPORT_TRACE'] == item]['loadingOrder'].unique()\n",
    "        test_order_belong_to_trace[item] = orders\n",
    "    return format_data_type(data, mode='test'), test_trace_set, test_order_belong_to_trace\n",
    "\n",
    "test_data_origin, test_trace_set, test_order_belong_to_trace = get_test_data_info(test_data_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_port_info():\n",
    "    port_data = {}\n",
    "    test_port_set = set()\n",
    "    for route in test_trace_set:\n",
    "        ports = route.split('-')\n",
    "        test_port_set = set.union(test_port_set, set(ports))\n",
    "    port_data_origin = pd.read_csv(port_path)\n",
    "    for item in port_data_origin.itertuples():\n",
    "        if getattr(item, 'TRANS_NODE_NAME') in test_port_set:\n",
    "            port_data[getattr(item, 'TRANS_NODE_NAME')] = {'LONGITUDE': getattr(item, 'LONGITUDE'),'LATITUDE': getattr(item, 'LATITUDE') }\n",
    "    return port_data\n",
    "port_data = get_port_info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_train_route_order_data(route):\n",
    "    route_order_speed_dis_time_path = os.path.join(route_order_folder_path, \"{}_speed_dis_time.csv\".format(route))\n",
    "    data_speed_dis_time = pd.read_csv(route_order_speed_dis_time_path,usecols = [1,2,3,4])   \n",
    "    return data_speed_dis_time\n",
    "\n",
    "def get_test_route_dis():\n",
    "    path = os.path.join(route_order_folder_path, \"route_dis_median.csv\")\n",
    "    data_speed_dis_time = pd.read_csv(path, names=['TRANSPORT_TRACE','total_dis']) \n",
    "    return data_speed_dis_time\n",
    "test_route_dis_origin = get_test_route_dis()\n",
    "test_route_distance = {}\n",
    "for index, row in test_route_dis_origin.iterrows():\n",
    "    test_route_distance[row[0]] = row[1]\n",
    "\n",
    "def get_test_data(route, order):\n",
    "    order_info_set = test_data_origin[test_data_origin['loadingOrder'] == order].sort_values(by='timestamp')\n",
    "#     print('=========================')\n",
    "#     print(route, order, order_info_set.shape)\n",
    "#     print(order_info_set)\n",
    "    order_info_set = order_info_set[order_info_set['speed'] >= 10]\n",
    "#     print(route, order, order_info_set.shape)\n",
    "    speed_median = order_info_set['speed'].median()\n",
    "    feature = pd.DataFrame({'loadingOrder':[order], 'speed_median':[speed_median], 'total_dis':[test_route_distance[route]]})\n",
    "    return feature.reset_index(drop=True)\n",
    "\n",
    "def mse_score_eval(preds, valid):\n",
    "    labels = valid.get_label()\n",
    "    scores = mean_squared_error(y_true=labels, y_pred=preds)\n",
    "    return 'mse_score', scores, True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_model(x, y, seed=981125, is_shuffle=True):\n",
    "    train_pred = np.zeros((x.shape[0], ))\n",
    "    n_splits = min(5, x.shape[0])\n",
    "    # Kfold\n",
    "    fold = KFold(n_splits=n_splits, shuffle=is_shuffle, random_state=seed)\n",
    "    kf_way = fold.split(x)\n",
    "    # params\n",
    "    params = {\n",
    "        'learning_rate': 0.01,\n",
    "        'boosting_type': 'gbdt',\n",
    "        'objective': 'regression',\n",
    "        'num_leaves': 36,\n",
    "        'feature_fraction': 0.6,\n",
    "        'bagging_fraction': 0.7,\n",
    "        'bagging_freq': 6,\n",
    "        'seed': 8,\n",
    "        'bagging_seed': 1,\n",
    "        'feature_fraction_seed': 7,\n",
    "        'min_data_in_leaf': 25,\n",
    "        'nthread': 8,\n",
    "        'verbose': 1,\n",
    "    }\n",
    "    # train\n",
    "    for n_fold, (train_idx, valid_idx) in enumerate(kf_way, start=1):\n",
    "        train_x, train_y = x.iloc[train_idx], y.iloc[train_idx]\n",
    "        valid_x, valid_y = x.iloc[valid_idx], y.iloc[valid_idx]\n",
    "        # 数据加载\n",
    "        n_train = lgb.Dataset(train_x, label=train_y)\n",
    "        n_valid = lgb.Dataset(valid_x, label=valid_y)\n",
    "        clf = lgb.train(\n",
    "            params=params,\n",
    "            train_set=n_train,\n",
    "            num_boost_round=3000,\n",
    "            valid_sets=[n_valid],\n",
    "            early_stopping_rounds=100,\n",
    "            verbose_eval=100,\n",
    "            feval=mse_score_eval\n",
    "        )\n",
    "        train_pred[valid_idx] = clf.predict(valid_x, num_iteration=clf.best_iteration)\n",
    "    return clf    \n",
    "    \n",
    "bad_route_list = ['CNSHK-CLVAP','CNYTN-ARENA','CNHKG-ARBUE','HKHKG-FRFOS','HONGKONG-BU']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "tags": [
     "outputPrepend"
    ]
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5/5 [00:00<00:00, 250.47it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training until validation scores don't improve for 100 rounds\n",
      "[100]\tvalid_0's l2: 8.28424e+10\tvalid_0's mse_score: 8.28424e+10\n",
      "Early stopping, best iteration is:\n",
      "[1]\tvalid_0's l2: 1.76208e+11\tvalid_0's mse_score: 1.76208e+11\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "[100]\tvalid_0's l2: 6.35293e+10\tvalid_0's mse_score: 6.35293e+10\n",
      "Early stopping, best iteration is:\n",
      "[1]\tvalid_0's l2: 1.62898e+11\tvalid_0's mse_score: 1.62898e+11\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "[100]\tvalid_0's l2: 1.18805e+11\tvalid_0's mse_score: 1.18805e+11\n",
      "Early stopping, best iteration is:\n",
      "[1]\tvalid_0's l2: 2.24898e+11\tvalid_0's mse_score: 2.24898e+11\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "[100]\tvalid_0's l2: 1.84605e+11\tvalid_0's mse_score: 1.84605e+11\n",
      "Early stopping, best iteration is:\n",
      "[1]\tvalid_0's l2: 2.84803e+11\tvalid_0's mse_score: 2.84803e+11\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "[100]\tvalid_0's l2: 7.73018e+10\tvalid_0's mse_score: 7.73018e+10\n",
      "Early stopping, best iteration is:\n",
      "[1]\tvalid_0's l2: 1.72755e+11\tvalid_0's mse_score: 1.72755e+11\n"
     ]
    }
   ],
   "source": [
    "train_data = pd.DataFrame()\n",
    "for route in tqdm(bad_route_list):\n",
    "    data_speed_dis_time = get_train_route_order_data(route)\n",
    "    train_data = train_data.append(data_speed_dis_time)\n",
    "train_data = train_data.reset_index(drop=True)\n",
    "train_data = train_data[train_data['speed_median'] >= 20].drop(['loadingOrder'], axis=1)\n",
    "\n",
    "features = [c for c in train_data.columns if c not in ['loadingOrder', 'label']]\n",
    "model_by_route = train_model(train_data[features], train_data['label'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# result.to_csv(result_path, index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "csv_3900_path = '../result_server_20200626_B_origin.csv'\n",
    "csv_3900_best = pd.read_csv(csv_3900_path)\n",
    "csv_3900_best['onboardDate'] = pd.to_datetime(csv_3900_best['onboardDate'], infer_datetime_format=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5/5 [00:00<00:00,  5.11it/s]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>loadingOrder</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>longitude</th>\n",
       "      <th>latitude</th>\n",
       "      <th>carrierName</th>\n",
       "      <th>vesselMMSI</th>\n",
       "      <th>onboardDate</th>\n",
       "      <th>ETA</th>\n",
       "      <th>creatDate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>AE223035353902</td>\n",
       "      <td>2019-07-03T21:16:48.000Z</td>\n",
       "      <td>120.093858</td>\n",
       "      <td>22.581320</td>\n",
       "      <td>OIEQNT</td>\n",
       "      <td>C2075927370</td>\n",
       "      <td>2019-07-02 04:12:48</td>\n",
       "      <td>2019/07/26  13:59:24</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>AE223035353902</td>\n",
       "      <td>2019-07-03T21:34:48.000Z</td>\n",
       "      <td>120.035707</td>\n",
       "      <td>22.617522</td>\n",
       "      <td>OIEQNT</td>\n",
       "      <td>C2075927370</td>\n",
       "      <td>2019-07-02 04:12:48</td>\n",
       "      <td>2019/07/26  13:59:24</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>AE223035353902</td>\n",
       "      <td>2019-07-03T21:51:18.000Z</td>\n",
       "      <td>119.981800</td>\n",
       "      <td>22.658465</td>\n",
       "      <td>OIEQNT</td>\n",
       "      <td>C2075927370</td>\n",
       "      <td>2019-07-02 04:12:48</td>\n",
       "      <td>2019/07/26  13:59:24</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>AE223035353902</td>\n",
       "      <td>2019-07-03T21:54:18.000Z</td>\n",
       "      <td>119.970845</td>\n",
       "      <td>22.668688</td>\n",
       "      <td>OIEQNT</td>\n",
       "      <td>C2075927370</td>\n",
       "      <td>2019-07-02 04:12:48</td>\n",
       "      <td>2019/07/26  13:59:24</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>AE223035353902</td>\n",
       "      <td>2019-07-03T22:11:08.000Z</td>\n",
       "      <td>119.953628</td>\n",
       "      <td>22.756897</td>\n",
       "      <td>OIEQNT</td>\n",
       "      <td>C2075927370</td>\n",
       "      <td>2019-07-02 04:12:48</td>\n",
       "      <td>2019/07/26  13:59:24</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34707</th>\n",
       "      <td>ZZ524449869421</td>\n",
       "      <td>2020-03-17T04:02:38.000Z</td>\n",
       "      <td>103.776707</td>\n",
       "      <td>1.252897</td>\n",
       "      <td>BHSOUA</td>\n",
       "      <td>P2595193878</td>\n",
       "      <td>2020-03-13 06:07:28</td>\n",
       "      <td>2020/04/03  13:50:32</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34708</th>\n",
       "      <td>ZZ524449869421</td>\n",
       "      <td>2020-03-17T04:03:18.000Z</td>\n",
       "      <td>103.776312</td>\n",
       "      <td>1.253418</td>\n",
       "      <td>BHSOUA</td>\n",
       "      <td>P2595193878</td>\n",
       "      <td>2020-03-13 06:07:28</td>\n",
       "      <td>2020/04/03  13:50:32</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34709</th>\n",
       "      <td>ZZ524449869421</td>\n",
       "      <td>2020-03-17T04:05:18.000Z</td>\n",
       "      <td>103.775175</td>\n",
       "      <td>1.254865</td>\n",
       "      <td>BHSOUA</td>\n",
       "      <td>P2595193878</td>\n",
       "      <td>2020-03-13 06:07:28</td>\n",
       "      <td>2020/04/03  13:50:32</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34710</th>\n",
       "      <td>ZZ524449869421</td>\n",
       "      <td>2020-03-17T04:05:58.000Z</td>\n",
       "      <td>103.774803</td>\n",
       "      <td>1.255285</td>\n",
       "      <td>BHSOUA</td>\n",
       "      <td>P2595193878</td>\n",
       "      <td>2020-03-13 06:07:28</td>\n",
       "      <td>2020/04/03  13:50:32</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34711</th>\n",
       "      <td>ZZ524449869421</td>\n",
       "      <td>2020-03-17T04:07:38.000Z</td>\n",
       "      <td>103.773883</td>\n",
       "      <td>1.256368</td>\n",
       "      <td>BHSOUA</td>\n",
       "      <td>P2595193878</td>\n",
       "      <td>2020-03-13 06:07:28</td>\n",
       "      <td>2020/04/03  13:50:32</td>\n",
       "      <td>2020/06/27  15:59:38</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>34712 rows × 9 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         loadingOrder                 timestamp   longitude   latitude  \\\n",
       "0      AE223035353902  2019-07-03T21:16:48.000Z  120.093858  22.581320   \n",
       "1      AE223035353902  2019-07-03T21:34:48.000Z  120.035707  22.617522   \n",
       "2      AE223035353902  2019-07-03T21:51:18.000Z  119.981800  22.658465   \n",
       "3      AE223035353902  2019-07-03T21:54:18.000Z  119.970845  22.668688   \n",
       "4      AE223035353902  2019-07-03T22:11:08.000Z  119.953628  22.756897   \n",
       "...               ...                       ...         ...        ...   \n",
       "34707  ZZ524449869421  2020-03-17T04:02:38.000Z  103.776707   1.252897   \n",
       "34708  ZZ524449869421  2020-03-17T04:03:18.000Z  103.776312   1.253418   \n",
       "34709  ZZ524449869421  2020-03-17T04:05:18.000Z  103.775175   1.254865   \n",
       "34710  ZZ524449869421  2020-03-17T04:05:58.000Z  103.774803   1.255285   \n",
       "34711  ZZ524449869421  2020-03-17T04:07:38.000Z  103.773883   1.256368   \n",
       "\n",
       "      carrierName   vesselMMSI         onboardDate                   ETA  \\\n",
       "0          OIEQNT  C2075927370 2019-07-02 04:12:48  2019/07/26  13:59:24   \n",
       "1          OIEQNT  C2075927370 2019-07-02 04:12:48  2019/07/26  13:59:24   \n",
       "2          OIEQNT  C2075927370 2019-07-02 04:12:48  2019/07/26  13:59:24   \n",
       "3          OIEQNT  C2075927370 2019-07-02 04:12:48  2019/07/26  13:59:24   \n",
       "4          OIEQNT  C2075927370 2019-07-02 04:12:48  2019/07/26  13:59:24   \n",
       "...           ...          ...                 ...                   ...   \n",
       "34707      BHSOUA  P2595193878 2020-03-13 06:07:28  2020/04/03  13:50:32   \n",
       "34708      BHSOUA  P2595193878 2020-03-13 06:07:28  2020/04/03  13:50:32   \n",
       "34709      BHSOUA  P2595193878 2020-03-13 06:07:28  2020/04/03  13:50:32   \n",
       "34710      BHSOUA  P2595193878 2020-03-13 06:07:28  2020/04/03  13:50:32   \n",
       "34711      BHSOUA  P2595193878 2020-03-13 06:07:28  2020/04/03  13:50:32   \n",
       "\n",
       "                  creatDate  \n",
       "0      2020/06/27  15:59:38  \n",
       "1      2020/06/27  15:59:38  \n",
       "2      2020/06/27  15:59:38  \n",
       "3      2020/06/27  15:59:38  \n",
       "4      2020/06/27  15:59:38  \n",
       "...                     ...  \n",
       "34707  2020/06/27  15:59:38  \n",
       "34708  2020/06/27  15:59:38  \n",
       "34709  2020/06/27  15:59:38  \n",
       "34710  2020/06/27  15:59:38  \n",
       "34711  2020/06/27  15:59:38  \n",
       "\n",
       "[34712 rows x 9 columns]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for route in tqdm(bad_route_list):\n",
    "    for order in test_order_belong_to_trace[route]:\n",
    "        test_order_data = get_test_data(route, order)\n",
    "        res = model_by_route.predict(test_order_data[features], num_iteration=model_by_route.best_iteration)\n",
    "        csv_3900_best.loc[csv_3900_best['loadingOrder'] == order, 'ETA'] = (csv_3900_best[csv_3900_best['loadingOrder'] == order]['onboardDate'] + pd.Timedelta(seconds=res[0])).apply(lambda x:x.strftime('%Y/%m/%d  %H:%M:%S'))\n",
    "        \n",
    "csv_3900_best.to_csv(result_path, index=False)\n",
    "csv_3900_best  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5/5 [00:00<00:00, 1001.74it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "FX658315757892\n",
      "GM373318338848\n",
      "HE273820450227\n",
      "HQ298919518932\n",
      "HV119475836181\n",
      "KN496453387986\n",
      "MZ696790961139\n",
      "NC185398487640\n",
      "NM983847866824\n",
      "ST695058399781\n",
      "XX932009788203\n",
      "YG453695887086\n",
      "YP105149249992\n",
      "YU488016730112\n",
      "HJ246261379392\n",
      "HV544902512699\n",
      "JU360847167491\n",
      "KM466086744301\n",
      "KW203223353208\n",
      "QD564688243325\n",
      "YC498927281293\n",
      "YI904717006355\n",
      "ZA229272050987\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "for route in tqdm(bad_route_list):\n",
    "    for order in test_order_belong_to_trace[route]:\n",
    "        print(order)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.7.6 64-bit ('AI': conda)",
   "language": "python",
   "name": "python37664bitaiconda6859e03b37c34f0182c9bde8073269f7"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
